package com.fernfx.xingtan.main.presenter;

import android.text.TextUtils;
import android.view.View;

import com.baidu.location.Address;
import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.TextureMapView;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.core.PoiInfo;
import com.baidu.mapapi.search.core.SearchResult;
import com.baidu.mapapi.search.geocode.GeoCodeResult;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeResult;
import com.baidu.mapapi.search.poi.OnGetPoiSearchResultListener;
import com.baidu.mapapi.search.poi.PoiDetailResult;
import com.baidu.mapapi.search.poi.PoiIndoorResult;
import com.baidu.mapapi.search.poi.PoiResult;
import com.baidu.mapapi.search.poi.PoiSearch;
import com.fernfx.xingtan.Constant;
import com.fernfx.xingtan.ConsumerApplication;
import com.fernfx.xingtan.common.base.BaseView;
import com.fernfx.xingtan.main.contract.SelectLocationContract;
import com.fernfx.xingtan.utils.CollectionUtil;
import com.fernfx.xingtan.utils.LogUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by admin on 2018/8/22.
 */

public class SelectLocationPresenter<P extends SelectLocationContract.View> implements SelectLocationContract.Presenter, BDLocationListener, OnGetGeoCoderResultListener, OnGetPoiSearchResultListener {
    private LocationClient mLocationClient;
    private BaiduMap mBaiduMap;
    double mLantitude;
    double mLongtitude;
    LatLng mLoactionLatLng;
    GeoCoder mGeoCoder = null;
    private boolean isFirstLoc = true; // 是否首次定位
    PoiSearch poiSearch;
    //定位推荐的集合
    private List<PoiInfo> mInfoList = new ArrayList<PoiInfo>();
    private P P;
    private String city, district;

    @Override
    public void init(BaseView view) {
        this.P = (P) view;
    }

    @Override
    public void request(Map<String, Object> requestArgsMap) {

    }

    @Override
    public BaiduMap initBaiduMap(TextureMapView tMapView) {
        mBaiduMap = tMapView.getMap();
        //设置没有缩小放大按钮
        tMapView.showZoomControls(true);
        //默认显示普通地图
        mBaiduMap.setMapType(BaiduMap.MAP_TYPE_NORMAL);
        //开启交通图
        //mBaiduMap.setTrafficEnabled(true);
        //开启热力图
        //mBaiduMap.setBaiduHeatMapEnabled(true);
        // 开启定位图层
        mBaiduMap.setMyLocationEnabled(true);
        //声明LocationClient类
        mLocationClient = new LocationClient(ConsumerApplication.getInstance());

        //配置定位SDK参数
        initLocation();
        mLocationClient.registerLocationListener(this);
        //开启定位
        mLocationClient.start();
        //图片点击事件，回到定位点
        mLocationClient.requestLocation();
        //调用定位推荐
        initRecommendArea();
        //初始化搜索
        poiSearch = PoiSearch.newInstance();
        poiSearch.setOnGetPoiSearchResultListener(this);
        return mBaiduMap;
    }

    public LocationClient getMLoactionLatLng() {
        return mLocationClient;
    }

    @Override
    public LatLng getCurrentLatLng() {
        return mLoactionLatLng;
    }

    //配置定位SDK参数
    private void initLocation() {
        LocationClientOption option = new LocationClientOption();
        option.setLocationMode(LocationClientOption.LocationMode.Hight_Accuracy
        );//可选，默认高精度，设置定位模式，高精度，低功耗，仅设备
        option.setCoorType("bd09ll");//可选，默认gcj02，设置返回的定位结果坐标系
        int span = Constant.ApplicationVariable.SPAN;
        option.setScanSpan(span);//可选，默认0，即仅定位一次，设置发起定位请求的间隔需要大于等于1000ms才是有效的
        option.setIsNeedAddress(true);//可选，设置是否需要地址信息，默认不需要
        option.setOpenGps(true);//可选，默认false,设置是否使用gps
        option.setLocationNotify(true);//可选，默认false，设置是否当GPS有效时按照1S/1次频率输出GPS结果
        option.setIsNeedLocationDescribe(true);//可选，默认false，设置是否需要位置语义化结果，可以在BDLocation
        // .getLocationDescribe里得到，结果类似于“在北京天安门附近”
        option.setIsNeedLocationPoiList(true);//可选，默认false，设置是否需要POI结果，可以在BDLocation.getPoiList里得到
        option.setIgnoreKillProcess(false);
        option.setOpenGps(true); // 打开gps

        //可选，默认true，定位SDK内部是一个SERVICE，并放到了独立进程，设置是否在stop的时候杀死这个进程，默认不杀死
        option.SetIgnoreCacheException(false);//可选，默认false，设置是否收集CRASH信息，默认收集
        option.setEnableSimulateGps(false);//可选，默认false，设置是否需要过滤GPS仿真结果，默认需要
        mLocationClient.setLocOption(option);
    }

    @Override
    public void onReceiveLocation(BDLocation location) {
        if (location == null || mBaiduMap == null)
            return;
        MyLocationData data = new MyLocationData.Builder()//
                // .direction(mCurrentX)//
                .accuracy(15)//
                .latitude(location.getLatitude())//
                .longitude(location.getLongitude())//
                .build();
        mBaiduMap.setMyLocationData(data);
        // 设置自己定义图标
        MyLocationConfiguration config = new MyLocationConfiguration(
                MyLocationConfiguration.LocationMode.NORMAL, true, null);
        mBaiduMap.setMyLocationConfigeration(config);

        mLantitude = location.getLatitude();
        mLongtitude = location.getLongitude();

        LatLng currentLatLng = new LatLng(mLantitude, mLongtitude);
        mLoactionLatLng = new LatLng(mLantitude, mLongtitude);

        if (TextUtils.isEmpty(city)) {
            city = location.getCity();
        }
        //区县
        district = location.getDistrict();

        // 是否第一次定位
        if (isFirstLoc) {
            isFirstLoc = false;
            // 实现动画跳转
            MapStatusUpdate u = MapStatusUpdateFactory
                    .newLatLng(currentLatLng);
            mBaiduMap.animateMapStatus(u);
            LatLng ll = new LatLng(mLantitude, mLongtitude);
            MapStatus.Builder builder = new MapStatus.Builder();
            builder.target(ll).zoom(19.5f);
            mBaiduMap.animateMapStatus(MapStatusUpdateFactory.newMapStatus(builder.build()));
            mGeoCoder.reverseGeoCode((new ReverseGeoCodeOption())
                    .location(currentLatLng));
            return;
        }
    }

    private void initRecommendArea() {
        mGeoCoder = GeoCoder.newInstance();
        mGeoCoder.setOnGetGeoCodeResultListener(this);
    }

    @Override
    public void onGetGeoCodeResult(GeoCodeResult result) {
        LogUtils.d("fff");
    }

    @Override
    public void onGetReverseGeoCodeResult(ReverseGeoCodeResult result) {
        if (!(result == null || result.error != SearchResult.ERRORNO.NO_ERROR)) {
            mInfoList.clear();
            // 将周边信息增加表
            if (result.getPoiList() != null) {
                List<PoiInfo> dataPoiInfoList = result.getPoiList();
                for (int i = 0; i < dataPoiInfoList.size(); i++) {
                    PoiInfo poiInfo = dataPoiInfoList.get(i);
                    mInfoList.add(poiInfo);
                }
                P.showRecommendLocation(mInfoList);
            }
        }
    }


    public PoiSearch getPoiSearch() {
        return poiSearch;
    }

    @Override
    public String getCity() {
        return city;
    }

    @Override
    public String getDistrict() {
        return district;
    }

    @Override
    public void onGetPoiResult(PoiResult poiResult) {
        List<PoiInfo> poiInfos = poiResult.getAllPoi();
        mInfoList.clear();
        if (poiInfos != null) {
            // 通知适配数据已改变
            mInfoList.addAll(poiInfos);
            P.searchLocation(mInfoList);
        }
    }

    @Override
    public void onGetPoiDetailResult(PoiDetailResult poiDetailResult) {

    }

    @Override
    public void onGetPoiIndoorResult(PoiIndoorResult poiIndoorResult) {

    }

    @Override
    public void detachView() {
        if (!CollectionUtil.isEmpty(mInfoList)) {
            mInfoList.clear();
            mInfoList = null;
        }
    }
}
